home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Applications / Nuntius 1.2 / src / Nuntius / UViewListView.cp < prev    next >
Encoding:
Text File  |  1994-02-20  |  11.5 KB  |  424 lines  |  [TEXT/MPS ]

  1. // Copyright © 1992 Peter Speck, speck@dat.ruc.dk. All rights reserved.
  2. // UViewListView.cp
  3.  
  4. #include "UViewListView.h"
  5.  
  6. #pragma segment MyViewTools
  7.  
  8. #define qDebugUpdateViews qDebug & 0
  9. #define qDebugScrollBits qDebug & 0
  10. #define qDebugRebuildFrames qDebug & 0
  11. #define qDebugAOSV qDebug & 0
  12.  
  13.  
  14. TViewListView::TViewListView()
  15. {
  16. }
  17.  
  18. pascal void TViewListView::Initialize()
  19. {
  20.     inherited::Initialize();
  21.     fIsAdjustingSubViewFrames = false;
  22.     fAddSeparatorAtBottom = false;
  23. }
  24.  
  25. pascal void TViewListView::ReadFields(TStream *aStream)
  26. {
  27.     inherited::ReadFields(aStream);
  28. }
  29.  
  30. pascal void TViewListView::DoPostCreate(TDocument *itsDocument)
  31. {
  32.     inherited::DoPostCreate(itsDocument);
  33. }
  34.  
  35. pascal void TViewListView::Free()
  36. {
  37.     inherited::Free();
  38. }
  39.  
  40. pascal void TViewListView::Draw(const VRect& area)
  41. {
  42.     inherited::Draw(area);
  43.     VCoordinate offset = 0;
  44.     Boolean gotOne = false;
  45.     // block for failure handling
  46.     {
  47.         CSubViewIterator iter(this);
  48.         for (TView *subView = iter.FirstSubView(); iter.More(); subView = iter.NextSubView())
  49.         {
  50.             if (gotOne)
  51.             {
  52.                 if (area.Contains(VPoint(area.left, offset)))
  53.                     DrawViewSeparator(offset);
  54.                 else if (area.Contains(VPoint(area.left, offset + GetSeparatorHeight() - 1)))
  55.                     DrawViewSeparator(offset);                
  56.             }
  57.             gotOne = true;
  58.             VRect frame;
  59.             subView->GetFrame(frame);
  60.             offset = frame.bottom;
  61.         }
  62.     }
  63.     if (fAddSeparatorAtBottom)
  64.     {
  65.         if (area.Contains(VPoint(area.left, offset)))
  66.             DrawViewSeparator(offset);
  67.         else if (area.Contains(VPoint(area.left, offset + GetSeparatorHeight() - 1)))
  68.             DrawViewSeparator(offset);
  69.     }
  70. }
  71.  
  72. pascal void TViewListView::SubViewChangedFrame(TView* theSubView,
  73.                                 const VRect& oldFrame, const VRect& newFrame, Boolean invalidate)
  74. {
  75.     inherited::SubViewChangedFrame(theSubView, oldFrame, newFrame, invalidate);
  76.     if (fIsAdjustingSubViewFrames)
  77.     {
  78. #if qDebugRebuildFrames
  79.         fprintf(stderr, "TViewListView::SubViewChangedFrame called while fIsAdjustingSubViewFrames == true\n");
  80. #endif
  81.     return;
  82.     }
  83.     UpdateSubViewFrames(theSubView, oldFrame, newFrame);
  84. //    RebuildSubViewFrames();
  85. }
  86.  
  87. void TViewListView::UpdateSubViewFrames(TView* theSubView,
  88.                                 const VRect& oldFrame, const VRect& newFrame)
  89. {
  90.     fIsAdjustingSubViewFrames = true;
  91.  
  92.     VRect fr;
  93.     VRect myFrame(0, 0, 0, 0);
  94.     VRect myOldFrame;
  95.     GetFrame(myOldFrame);
  96.     CSubViewIterator iter(this);
  97.     for (TView *view = iter.FirstSubView(); iter.More(); view = iter.NextSubView())
  98.     {
  99.         view->GetFrame(fr);
  100.         myFrame = myFrame | fr;
  101.         if (view == theSubView)
  102.             break;
  103.     }
  104.     if (!view)
  105.         Failure(minErr, 0);
  106.     theSubView->GetFrame(fr);
  107.     myFrame = myFrame | fr;    
  108.     VCoordinate scrollOffset = (newFrame.bottom - newFrame.top) - (oldFrame.bottom - oldFrame.top);
  109. #if qDebugUpdateViews
  110.     VCoordinate offset = newFrame.top - oldFrame.top;
  111.     fprintf(stderr, "ChangeView: %s -> ", (char*)oldFrame);
  112.     fprintf(stderr, "%s, Δ = %ld, scroll = %ld\n", (char*)newFrame, offset, scrollOffset);
  113. #endif
  114.     VCoordinate vOffset = newFrame.bottom;
  115.     // update rest of views:
  116.     for (view = iter.NextSubView(); iter.More(); view = iter.NextSubView())
  117.     {
  118.         vOffset += GetSeparatorHeight();
  119.         view->GetFrame(fr);
  120.         VRect newFr(fr);
  121.         newFr.top = vOffset;
  122.         newFr.bottom = newFr.top + (fr.bottom - fr.top);
  123.         view->SetFrame(newFr, !kRedraw);
  124.         myFrame = myFrame | newFr;
  125. #if qDebugUpdateViews
  126.         fprintf(stderr, "Adjusted subview: %s -> ", (char*)fr);
  127.         fprintf(stderr, "%s\n", (char*)newFr);
  128. #endif
  129.         vOffset += (fr.bottom - fr.top);
  130.     }
  131.     if (fAddSeparatorAtBottom)
  132.         myFrame.bottom += GetSeparatorHeight();
  133.     CheckNewFrame(myFrame);    
  134.     if (myFrame.bottom > myOldFrame.bottom)
  135.         SetFrame(myFrame, !kRedraw);
  136.     DoScrollBits(oldFrame.bottom, scrollOffset);
  137.     if (myFrame.bottom < myOldFrame.bottom)
  138.         SetFrame(myFrame, kRedraw); //@@ !kRedraw -> kRedraw
  139. #if qDebugUpdateViews
  140.     fprintf(stderr, "MyNewFrame = %s, ", (char*)myFrame);
  141.     fprintf(stderr, "myOldFrame = %s\n", (char*)myOldFrame);
  142. #endif
  143.     if (newFrame.top >= myOldFrame.bottom)
  144.     {
  145.         // new view: invalidate separator
  146.         VRect vr(myOldFrame.left, myOldFrame.bottom - GetSeparatorHeight(), myOldFrame.right, newFrame.top);
  147.         Focus();
  148.         InvalidateVRect(vr);
  149. #if qDebugUpdateViews
  150.         fprintf(stderr, "Invalidates %s: got new subView\n", (char*)vr);
  151. #endif
  152.         if (fAddSeparatorAtBottom)
  153.         {
  154.             vr = myFrame;
  155.             vr.top = newFrame.top - GetSeparatorHeight();
  156.             Focus();
  157.             InvalidateVRect(vr);
  158. #if qDebugUpdateViews
  159.             fprintf(stderr, "Invalidates %s separator at bottom: got new subView\n", (char*)vr);
  160. #endif
  161.         }
  162.     }
  163.     VCoordinate grow = (newFrame.bottom - newFrame.top) - (oldFrame.bottom - oldFrame.top);
  164.     if (grow > 0)
  165.     {
  166.         // view is grown bigger, invalidate new part
  167.         VRect vr(newFrame);
  168.         vr.top = vr.top + (oldFrame.bottom - oldFrame.top);
  169.         Focus();
  170.         InvalidateVRect(vr);
  171. #if qDebugUpdateViews
  172.         fprintf(stderr, "Invalidates %s as theSubView is grown bigger\n", (char*)vr);
  173. #endif
  174.     }
  175. #if 0
  176.     if (myFrame.bottom < myOldFrame.bottom)
  177.     {
  178.         // view is smaller, update non-used part of TViewListView
  179.         VRect vr(myOldFrame);
  180.         vr.top = myFrame.bottom;
  181.         Focus();
  182.         InvalidateVRect(vr);
  183. #if qDebugUpdateViews
  184.         fprintf(stderr, "Invalidates %s as myFrame is grown smaller\n", (char*)vr);
  185. #endif
  186.     }
  187. #endif
  188. #if qDebugUpdateViews
  189.     fprintf(stderr, "\n");
  190. #endif
  191.     fIsAdjustingSubViewFrames = false;
  192. }
  193.  
  194. void TViewListView::DoScrollBits(VCoordinate vFrom, VCoordinate offset)
  195. {
  196.     if (!offset)
  197.         return;
  198.     Focus();
  199.     VRect visible;
  200.     GetVisibleRect(visible);
  201.     VRect moveFromVRect, moveToVRect;
  202.     GetFrame(moveFromVRect);
  203.     moveFromVRect.top = vFrom;
  204.     moveToVRect = moveFromVRect;
  205.     moveToVRect.top += offset;
  206.     moveToVRect.bottom += offset;
  207.     if (visible.bottom < moveFromVRect.top)
  208.     {
  209. #if qDebugScrollBits
  210.         fprintf(stderr, "Scroll: ¬vis: %s -> ", (char*)moveFromVRect);
  211.         fprintf(stderr, "%s, ", (char*)moveToVRect);
  212.         fprintf(stderr, "vis = %s\n", (char*)visible);
  213. #endif
  214.         Focus();
  215.         InvalidateVRect(moveToVRect);
  216.         return;
  217.     }
  218.     VRect visibleMoveRect = (moveFromVRect | moveToVRect) & visible;
  219. #if qDebugScrollBits
  220.     fprintf(stderr, "Scroll: %s -> ", (char*)moveFromVRect);
  221.     fprintf(stderr, "%s, ", (char*)moveToVRect);
  222.     fprintf(stderr, "move = %s\n", (char*)visibleMoveRect);
  223. #endif
  224. #if qDebugScrollBits
  225.     if (visibleMoveRect.Empty())
  226.         fprintf(stderr, "Scroll: visibleMoveRect was empty, should not have been it\n");
  227. #endif
  228. /*
  229.     if (offset > 0)
  230.     {
  231.         VRect myNewFrame(moveToVRect);
  232.         myNewFrame.top = 0;
  233.         SetFrame(myNewFrame, !kRedraw);
  234.     }
  235. */
  236.     CRect qdMoveRect;
  237.     ViewToQDRect(visibleMoveRect, qdMoveRect);
  238. #if qDebugScrollBits
  239.     fprintf(stderr, "Scroll: qdMoveRect = %s\n", (char*)qdMoveRect);
  240. #endif
  241.     CPoint delta(0, short(offset));
  242. #if qDebugScrollBits
  243.     fprintf(stderr, "Scroll: delta = %s\n", (char*)delta);
  244. #endif
  245.     if (delta.v)
  246.     {
  247.         Focus();
  248.         CTemporaryRegion updateRgn;
  249.         ScrollRect(qdMoveRect, delta.h, delta.v, updateRgn);
  250.         InvalidateRegion(updateRgn);
  251. //qdMoveRect.right = 10;
  252. //FillRect(qdMoveRect, qd.ltGray);
  253.     }
  254. }
  255.  
  256. void TViewListView::RebuildSubViewFrames()
  257. {
  258.     if (!fSubViews || !fSubViews->GetSize())
  259.     {
  260.         SetFrame(VRect(0, 0, 0, 0), kRedraw);
  261.         return;
  262.     }
  263.     FailInfo fi;
  264.     if (fi.Try())
  265.     {    
  266.         fIsAdjustingSubViewFrames = true;
  267.         VCoordinate curHeight = 0;
  268.         Boolean gotOne = false;
  269.         VRect myFrame(0, 0, 0, 0);
  270.         VRect myOldFrame;
  271.         GetFrame(myOldFrame);
  272. #if qDebugRebuildFrames
  273.         fprintf(stderr, "TViewListView, begins update of subview frames, fAddSeparatorAtBottom = %hd\n", fAddSeparatorAtBottom);
  274. #endif
  275.         // block for failure handling
  276.         {
  277.             ArrayIndex maxIndex = fSubViews->GetSize();
  278.             for (ArrayIndex index = 1; index <= maxIndex; index++)
  279.             {
  280.                 TView *subView = (TView*)fSubViews->At(index);
  281.                 if (gotOne)
  282.                     curHeight += GetSeparatorHeight();
  283.                 gotOne = true;
  284.                 VRect oldFrame, newFrame;
  285.                 subView->GetFrame(oldFrame);
  286.                 VCoordinate offset = curHeight - oldFrame.top;
  287.                 newFrame = oldFrame;
  288.                 newFrame.top += offset;
  289.                 newFrame.bottom += offset;
  290. #if qDebugRebuildFrames
  291.                 fprintf(stderr, "  move: %s -> ", (char*)oldFrame);
  292.                 fprintf(stderr, "%s, ", (char*)newFrame);
  293.                 fprintf(stderr, "Δ = %ld, curHeight = %ld\n", offset, curHeight);
  294. #endif
  295.                 myFrame = myFrame | newFrame;
  296.                 VRect myCurrentFrame;
  297.                 GetFrame(myCurrentFrame);
  298.                 if (myFrame.bottom > myCurrentFrame.bottom)
  299.                     SetFrame(myFrame, !kRedraw);
  300.                 subView->SetFrame(newFrame, !kRedraw);
  301.                 VCoordinate grow = (newFrame.bottom - newFrame.top) - (oldFrame.bottom - oldFrame.top);
  302.  
  303.                 if (offset)
  304.                 {
  305.                     VCoordinate top = oldFrame.top;
  306.                     if (top > 0) // if not first view, include separator
  307.                         top -= GetSeparatorHeight();
  308.                     DoScrollBits(top, offset);
  309.  
  310.                     VCoordinate vAdjust = curHeight + (newFrame.bottom - newFrame.top);
  311.                     CSubViewIterator adjustIter(this, index + 1, kMaxLong, kIterateForward);
  312.                     for (TView *adjustView = adjustIter.FirstSubView(); adjustIter.More(); adjustView = adjustIter.NextSubView())
  313.                     {
  314.                         vAdjust += GetSeparatorHeight();
  315.                         VRect fr;
  316.                         adjustView->GetFrame(fr);
  317.                         VCoordinate adjustOffset = vAdjust - fr.top;
  318.                         VRect newFr(fr);
  319.                         newFr.top += adjustOffset;
  320.                         newFr.bottom += adjustOffset;
  321.                         adjustView->SetFrame(newFr, !kRedraw);
  322. #if qDebugRebuildFrames
  323.                         fprintf(stderr, "  ScrollAdjust: %s -> ", (char*)fr);
  324.                         fprintf(stderr, "%s, Δ = %ld\n", (char*)newFr, adjustOffset);
  325. #endif
  326.                         vAdjust += (fr.bottom - fr.top);
  327.                     }
  328.                 }
  329.                 else if (index == maxIndex && grow > 0)
  330.                 {
  331.                     // view is grown bigger, invalidate new part
  332.                     VRect vr(newFrame);
  333.                     vr.top += (oldFrame.bottom - oldFrame.top);
  334.                     Focus();
  335.                     InvalidateVRect(vr);
  336. #if qDebug
  337.                     fprintf(stderr, "  LastView is grown bigger, %s is invalidated\n", (char*)vr);
  338. #endif
  339.                 }
  340.                 curHeight += newFrame.bottom - newFrame.top;
  341.             }
  342.         }
  343.         if (fAddSeparatorAtBottom)
  344.             myFrame.bottom += GetSeparatorHeight();
  345.         CheckNewFrame(myFrame);    
  346. #if qDebugRebuildFrames
  347.         fprintf(stderr, "end of update, myFrame = %s\n", (char*)myFrame);
  348.         fprintf(stderr, "\n");
  349. #endif
  350.         SetFrame(myFrame, kRedraw);
  351.         fIsAdjustingSubViewFrames = false;
  352.         fi.Success();
  353.     }
  354.     else // fail
  355.     {
  356.         fIsAdjustingSubViewFrames = false;
  357.         fi.ReSignal();
  358.     }
  359. }
  360.  
  361. void TViewListView::AdjustOneSubView(TView *view, VRect oldFrame, VRect newFrame, VCoordinate offset)
  362. {
  363.     Focus();
  364.     VRect visible;
  365.     GetVisibleRect(visible);
  366.     if (visible.bottom < oldFrame.top || visible.top > oldFrame.bottom)
  367.     {
  368. #if qDebugAOSV
  369.         fprintf(stderr, "AOSV: ¬vis: %s -> ", (char*)oldFrame);
  370.         fprintf(stderr, "%s, ", (char*)newFrame);
  371.         fprintf(stderr, "vis = %s\n", (char*)visible);
  372. #endif
  373.         view->SetFrame(newFrame, !kRedraw);
  374.         return;
  375.     }
  376.     VRect moveFromVRect(oldFrame[topLeft], fSize);
  377.     if (moveFromVRect.top > 0) // if not first view, include separator
  378.         moveFromVRect.top -= GetSeparatorHeight();
  379.     VRect moveToVRect(moveFromVRect);
  380.     moveToVRect.top += offset;
  381.     moveToVRect.bottom += offset;
  382.     VRect visibleMoveRect = (moveFromVRect | moveToVRect) & visible;
  383. #if qDebugAOSV
  384.     fprintf(stderr, "AOSV: %s -> ", (char*)moveFromVRect);
  385.     fprintf(stderr, "%s, ", (char*)moveToVRect);
  386.     fprintf(stderr, "move = %s\n", (char*)visibleMoveRect);
  387. #endif
  388. #if qDebugAOSV
  389.     if (visibleMoveRect.Empty())
  390.         fprintf(stderr, "AOSV: visibleMoveRect was empty, should not have been it\n");
  391. #endif
  392.     CRect qdMoveRect;
  393.     ViewToQDRect(visibleMoveRect, qdMoveRect);
  394. #if qDebugAOSV
  395.     fprintf(stderr, "AOSV: qdMoveRect = %s\n", (char*)qdMoveRect);
  396. #endif
  397.     CPoint delta(0, short(offset));
  398. #if qDebugAOSV
  399.     fprintf(stderr, "AOSV: delta = %s\n", (char*)delta);
  400. #endif
  401.     if (delta.v)
  402.     {
  403.         Focus();
  404.         CTemporaryRegion updateRgn;
  405.         ScrollRect(qdMoveRect, delta.h, delta.v, updateRgn);
  406.         InvalidateRegion(updateRgn);
  407.     }
  408.     view->SetFrame(newFrame, !kRedraw);
  409. }
  410.  
  411. VCoordinate TViewListView::GetSeparatorHeight()
  412. {
  413.     SubClassResponsibility();
  414.     return 0;
  415. }
  416.  
  417. void TViewListView::CheckNewFrame(VRect & /* newFrame */)
  418. {
  419. }
  420.  
  421. void TViewListView::DrawViewSeparator(VCoordinate /* vOffset */)
  422. {
  423. }
  424.